
window.onload = function(){
	g = new Game(document.getElementById('reversi-board'));
	g.start()
}

var directions = [
	[-1, 0], [-1, -1], [-1, 1],
	[0, -1], [0, 1], 
	[1, 0], [1, -1], [1, 1]
],
	itemType = {
		empty: 0,
		black: 1,
		white: 2
	},
	colors = ['white', 'black', 'blue'];

function Game(){
	this.init.apply(this, arguments);
}
Game.prototype = {
	init: function(boardDom){
		this.generateBoard(boardDom)
		this.prepare();
	},
	start: function(){
		this.reversi.setItem(3, 3, 1);
		this.reversi.setItem(3, 4, 2);
		this.reversi.setItem(4, 3, 2);
		this.reversi.setItem(4, 4, 1);
		this.updateBoard();
		this.nextTurn();
		//this.startProcessing();
	},
	generateBoard: function(boardDom){
		var tr_list = [], td_list = [];
		var i, j;
		for( i = 0; i < 8; i++ ){
			td_list.length = 0;
			for( j = 0; j < 8; j++ ){
				td_list.push(format('<td rowIndex="%s" colIndex="%s">&nbsp;</td>', i, j));
			}
			tr_list.push(td_list.join(''));
		}
		boardDom.innerHTML = ('<table cellspacing="0" cellpadding="0" border="0"><tbody>' +
		'<tr>' + tr_list.join('</tr><tr>') + '</tr>' +
		'</tbody></table>');
		this.canvas = boardDom.getElementsByTagName('table')[0];
	},
	prepare: function(){
		var game = this;
		this.canvas.onclick = function(event){
			event = event || window.event;
			var target = event.target || event.srcElement || document;
			// check if target is a textnode (safari)
			if ( event.target.nodeType == 3 )
				event.target = event.target.parentNode;
			if( event.target.tagName == 'TD' ){
				var td = event.target,
					rowIndex = parseInt(td.getAttribute('rowIndex')),
					colIndex = parseInt(td.getAttribute('colIndex'));
				var item = game.getTurnItem();
				if( game.reversi.place(rowIndex, colIndex, item) ){
					game.nextTurn();
					game.updateBoard();
					if( game.reversi.isFull() ){
						alert( game.reversi.getCount(itemType.black) + ':' + 
								game.reversi.getCount(itemType.white) )
					}
				}
			}
		}
		this.reversi = new Reversi();
	},
	startProcessing: function(){
		this.timer = window.setInterval(function(){ game.process(); }, 50);
	},
	getTurnItem: function(){
		return this.currentTurnItem;
	},
	nextTurn: function(){
		this.currentTurnItem = (this.currentTurnItem === 1 ? 2 : 1)
	},
	process: function(){
	},
	updateBoard: function(){
		var row, col;
		for( row = 0; row < 8; row++ ){
			for( col = 0; col < 8; col++ ){
				this.canvas.rows[row].cells[col].style.backgroundColor = colors[this.reversi.getItem(row, col)];
			}
		}
	}
}

function Reversi(){
	this.init()
}
Reversi.prototype = {
	init: function(){
		this.board = new Array(8);
		var i, j;
		for( i = 0, j = this.board.length; i < j; i++ ){
			this.board[i] = new Array(8);
		}
		this.itemsNeedToRevert = [];
	},
	place: function(row, col, item){
		if( this.canPlace(row, col, item) ){
			this.board[row][col] = item;
			this.updateBoard(row, col);
			return true;
		}
		return false;
	},
	canPlace: function(row, col, item){
		var otherSideItem, i, j, d, r, c, t;
		for( i = 0, j = directions.length; i < j; i++ ){
			d = directions[i];
			r = row + d[0];
			c = col + d[1];
			t = this.getItem(r, c);
			if( t && t != item ){
				do{
					r = r + d[0];
					c = c + d[1];
				}while( this.getItem(r, c) == t );
				if( this.getItem(r, c) == item ){
					return true;
				}
			}
		}
	},
	updateBoard: function(row, col){
		var otherSideItem, i, j, d, r, c, t,
			otherSideItemList = [];
		this.itemsNeedToRevert.length = 0;
		var item = this.board[row][col];
		for( i = 0, j = directions.length; i < j; i++ ){
			d = directions[i];
			r = row + d[0];
			c = col + d[1];
			t = this.getItem(r, c)
			otherSideItemList.length = 0;
			if( t && t != item ){
				do{
					otherSideItemList.push([r, c]);
					r = r + d[0];
					c = c + d[1];
				}while( t == this.getItem(r, c) );
				t = this.getItem(r, c);
				if( this.getItem(r, c) == item ){
					this.itemsNeedToRevert = this.itemsNeedToRevert.concat( otherSideItemList );
				}
			}
		}
		for( i = 0, j = this.itemsNeedToRevert.length; i < j; i++ ){
			t = this.itemsNeedToRevert[i];
			this.setItem(t[0], t[1], item);
		}
	},
	isFull: function(){
		var row, col, item;
		for( row = 0; row < 8; row++ ){
			for( col = 0; col < 8; col++ ){
				item = this.getItem(row, col);
				if( item != itemType.black && item != itemType.white ){
					return false;
				}
			}
		}
		return true;
	},
	isEmpty: function(row, col){
		return this.getItem(row, col) == itemType.empty;
	},
	getItem: function(row, col){
		var board = this.board;
		return (row >= 0 && row < board.length &&
				col >= 0 && col < board[row].length) ?  board[row][col] : null;
	},
	setItem: function(row, col, item){
		this.board[row][col] = item;
	},
	getCount: function(item){
		var row, col, item;
		this.counts = [0, 0, 0];
		for( row = 0; row < 8; row++ ){
			for( col = 0; col < 8; col++ ){
				item = this.getItem(row, col);
				if( item == itemType.black ){
					this.counts[itemType.black] ++
				}else if( item != itemType.white ){
					this.counts[itemType.white] ++
				}
			}
		}
	}
}

function format(pat /*variables to replace %s*/){
	var i = 1;
	while( i < arguments.length )
		pat = pat.replace('%s', arguments[i++]);
	return pat;
}

